import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { PrismaService } from 'src/prisma.service';
import * as crypto from 'crypto';
import { MailService } from 'src/mail/mail.service';
import { User } from './entities/user.entity';
import { GetUserInfoDto } from './dto/get-userinfo.dto';
import { plainToClass } from 'class-transformer';

@Injectable()
export class UserService {
  @Inject()
  prismaService: PrismaService;

  @Inject()
  mailService: MailService;

  private verificationCodes: {
    [email: string]: { code: string; expiresAt: Date };
  } = {};

  // 创建用户
  async createUser(createUserDto: CreateUserDto): Promise<User> {
    // 先验证一下验证码
    this.validateVerificationCode(
      createUserDto.email,
      createUserDto.verifyCode,
    );
    // 删除验证码
    const hash = crypto
      .createHash('md5')
      .update(createUserDto.password)
      .digest('hex');
    const res = await this.prismaService.user.create({
      // 1是用户，0是管理员
      data: {
        username: createUserDto.username,
        email: createUserDto.email,
        role: 1,
        password: hash,
      },
      include: {
        avatarFile: true,
      },
    });

    return res;
  }

  // 修改个人信息
  async updateUser(updateUserDto: UpdateUserDto): Promise<User> {
    console.log("🚀 ~ UserService ~ updateUser ~ updateUserDto:", updateUserDto)
    return await this.prismaService.user.update({
      where: { id: updateUserDto.id },
      data: updateUserDto,
      include: {
        avatarFile: true,
      },
    });
  }

  // 登录
  // async loginUser(loginUserDto: LoginUserDto) {
  //   const hash = crypto
  //     .createHash('md5')
  //     .update(loginUserDto.password)
  //     .digest('hex');
  //   const res = await this.prismaService.user.findUnique({
  //     where: { email: loginUserDto.email, password: hash },
  //   });
  //   return res;
  // }

  // 发送验证码
  async sendEmailCode(email: string) {
    const code = this.generateNumericCode(6);
    this.verificationCodes[email] = {
      code,
      expiresAt: new Date(Date.now() + 10 * 60 * 1000), // 10分钟后过期
    };
    await this.mailService.sendMail(email, `您的验证码是：${code}`);
    return '发送成功';
  }

  // 根据userName和password寻找user
  async findUser(email: string, password: string) {
    const hash = crypto.createHash('md5').update(password).digest('hex');
    const res = await this.prismaService.user.findUnique({
      where: { email, password: hash },
    });
    return res;
  }

  // 生成随机验证码
  private generateNumericCode(length: number): string {
    let code = '';
    for (let i = 0; i < length; i++) {
      code += Math.floor(Math.random() * 10); // 生成0-9的随机数字
    }
    return code;
  }

  // 验证存储的验证码
  private validateVerificationCode(email: string, code: string): boolean {
    const verification = this.verificationCodes[email];

    if (!verification) {
      throw new HttpException('验证码未找到或已过期', HttpStatus.BAD_REQUEST);
    }

    if (verification.code !== code) {
      throw new HttpException('验证码不正确', HttpStatus.BAD_REQUEST);
    }

    if (new Date() > verification.expiresAt) {
      delete this.verificationCodes[email]; // 删除过期的验证码
      throw new HttpException('验证码已过期', HttpStatus.BAD_REQUEST);
    }

    // 验证成功
    delete this.verificationCodes[email]; // 验证成功后删除验证码
    return true;
  }

  // 获取用户列表
  async getUserList(): Promise<User[]> {
    const users = await this.prismaService.user.findMany({
      include: {
        avatarFile: true,
      },
      orderBy: {
        createdAt: 'desc',
      },
      where: {
        isDeleted: false,
      },
    });
    return users;
  }

  // 删除用户
  async deleteUser(id: number): Promise<User> {
    try {
      return await this.prismaService.user.update({
        where: { id },
        include: {
          avatarFile: true,
        },
        data: {
          isDeleted: true,
        },
      });
    } catch {
      throw new HttpException('用户不存在', HttpStatus.NOT_FOUND);
    }
  }

  // 获取用户信息
  async getUserInfo(userId: number) {
    const articleRelationObject = {
      include: {
        comments: {
          include: {
            user: true,
          },
        },
        views: true,
        likes: true,
        user: {
          include: {
            avatarFile: true,
          },
        },
      },
    };
    const result = await this.prismaService.user.findFirstOrThrow({
      where: { id: userId },
      include: {
        avatarFile: true,
        comments: {
          include: {
            article: articleRelationObject,
            user: {
              include: {
                avatarFile: true,
              },
            },
          },
          take: 10,
        },
        articles: articleRelationObject,
        views: {
          include: {
            article: articleRelationObject,
          },
          take: 10,
        },
        actions: true,
        likes: {
          include: {
            article: articleRelationObject,
          },
          take: 10,
        },
      },
    });
    return plainToClass(GetUserInfoDto, result);
  }
}
